<template>
    <div class="w-[100%]">
        <n-spin :show="spinLoading">
            <n-upload v-model:file-list="uploadFileList" action="" :max="props.maxFile" :accept="acceptType"
                :multiple="props.multiple" @remove="handleRemove" @finish="handleFinish"
                @update:file-list="handleFileListChange" @error="handleError" :custom-request="customRequest"
                @before-upload="beforeUpload" @preview="handlePreview">
                <slot>
                    <n-button><i class="i-fe:plus mr-6"></i> {{ uploadName }}</n-button>
                </slot>
            </n-upload>
        </n-spin>
        <!-- 图片预览 -->
        <n-image-group class="mt-12" show-toolbar-tooltip v-if="fileType == 'image'">
            <n-space>
                <n-image border="1px solid #dedede" class="w-100 h-100 radius-xl" object-fit="contain"
                    v-for="item in uploadFileList" :src="item.url" />
            </n-space>
        </n-image-group>
        <!-- 视频预览 -->
        <MeModal ref="modalRef" width="60vw" :showFooter="false">
            <video class="w-[100%]" :src="videoUrl" controls></video>
        </MeModal>
    </div>
</template>

<script setup>
import { isArray } from '@/utils/is.js'
import { MeModal } from '@/components'
import { getFileType, getFileAcceptType } from './index.js'
import ossUpload from '@/utils/oss.js'
import { computed, onMounted, watch } from 'vue'

const emits = defineEmits(['uploadChange', 'uploadSuccess', 'uploadRemove'])

const props = defineProps({
    fileList: { // 文件列表 {url:'链接',name:'名称',id:'uid',status: 'finished'}
        type: Array,
        default: () => [],
    },
    fileType: { // 文件类型
        type: String,
        default: 'image'
    },
    multiple: { // 是否多选
        type: Boolean,
        default: false,
    },
    isFile: { // 是否文件流
        type: Boolean,
        default: false,
    },
    maxFile: { // 允许上传几个文件
        type: Number,
        default: 1,
    },
    uploadName: {
        type: String,
        default: '上传文件',
    },
    maxSize: { // 最大文件,单位MB 默认:200
        type: Number,
    },
    errMsg: { // 错误提示 默认:'文件上传异常,请稍后重试...'
        type: String,
    },
    ossOldUrl: { // oss地址
        type: [String, Number],
        default: '',
    },
    ossFolder: { // oss文件夹
        type: [String, Number],
        default: '',
    }
})

const acceptType = getFileAcceptType(props.fileType);

const spinLoading = ref(false);
const uploadFileList = ref([]);

watch(() => props.fileList, (newValue, oldValue) => {
    if (isArray(newValue) && newValue) {
        uploadFileList.value = newValue.map(item => {
            if (!item.status) {
                return {
                    ...item,
                    status: 'finished',
                }
            } else {
                return item
            }
        });
    }
}, {
    deep: true,
    immediate: true,
});

const beforeUpload = (data) => {
    // console.log('beforeUpload', data)
    let type = data.file.file?.type;
    let typeList = getFileType(props.fileType);
    if (!typeList.includes(type)) {
        $message.error(`只能上传${acceptType}格式的文件，请重新上传`);
        return false;
    }
    return true;
}
const customRequest = ({
    file,
    onFinish,
    onError,
    onProgress
}) => {
    // console.log('ossUpload-file', file);

    spinLoading.value = true;
    if (props.isFile) {
        spinLoading.value = false;
        onFinish()
    } else {
        let ossOldUrl = props.ossOldUrl && props.ossOldUrl.length ? props.ossOldUrl[0].url : '';

        ossUpload(
            {
                file: file.file,
                maxSize: props.maxSize,
                errMsg: props.errMsg,
                ossOldUrl: ossOldUrl,
                ossFolder: props.ossFolder,
            },
            (res) => {
                console.log(res, '上传返回的res');
                onProgress({ percent: Math.ceil(res.progress) });
                if (res.url) {
                    setTimeout(() => {
                        spinLoading.value = false;
                        $message.success('上传成功')
                        file.url = res.url;
                        // file.url = URL.createObjectURL(file.file);
                        console.log('上传结束', uploadFileList.value);
                        onFinish()
                    }, 1000)
                }
            }
        ).catch(err => {
            spinLoading.value = false;
            console.log('uploadError', err);
            onError();
        });
    }
};

const handleFinish = (data) => { // 上传完成
    // console.log('handleFinish', data);
    emits('uploadSuccess', data);
}
const handleFileListChange = (data) => { // 列表改变
    console.log('handleFileListChange', data);
    console.log('上传改变', uploadFileList.value);
    emits('uploadChange', uploadFileList.value);
}
const handleRemove = (data) => { // 删除
    // console.log('handleRemove', data);
    emits('uploadRemove', data);
}
const handleError = (data) => { // 上传异常
    console.log('handleError', data);
}
const videoUrl = ref({});
const modalRef = ref(null);
const handlePreview = (data, detail) => { // 预览
    console.log('handlePreview', data);
    if (props.fileType == 'image') {
        detail.event.preventDefault(); // 阻止a标签默认跳转
    } else if (props.fileType == 'video') {
        detail.event.preventDefault(); // 阻止a标签默认跳转
        videoUrl.value = data.url;
        modalRef.value.open();
    }
}
</script>

<style lang="scss" scoped>
:deep(.n-upload-file-list) {
    max-height: 500px;
    overflow: auto;
}
</style>